package org.fxml.managers {
	import org.fxml.commands.Command;

	import flash.events.Event;
	import flash.events.EventDispatcher;

	/**
	 * @author jordandoczy
	 */
	public class CommandManager extends EventDispatcher {
		
		private var _index:uint = 0;
		private var _isSequential:Boolean = true;
		private var _items:Array = new Array();
		private var _isWorking:Boolean = false;
		
		public function CommandManager(){}
		
		public function addCommand(command:Command):void{
			_items.push(command);
		}
		
		public function get currentItem():Command{
			return _items[_index];
		}
		
		public function get isSequential():Boolean{
			return _isSequential;
		}
		public function set isSequential(value:Boolean):void{
			if(_isWorking) return;
			_isSequential = value;
		}
		
		public function get isWorking():Boolean{
			return _isWorking;
		}
		
		public function reset():void{
			_index = 0;
			_isWorking = false;
			removeEvents();
			_items = [];
		}
		
		public function start():void{ trigger(); }
		public function trigger():void{
			_isWorking = true;
			
			if(_items.length == 0 || _index == _items.length){
				complete();
			}
			else if(isSequential){
				executeItem(_index);
			}
			else{
				for (var i:Number=0; i<_items.length; i++){
					executeItem(i);
				}
			}	
		}
		
		protected function complete():void{
			_isWorking = false;
			dispatchEvent(new Event(Event.COMPLETE));
		}
		
		protected function executeItem(index:uint):void{
			var command:Command = Command(_items[index]);
			command.addEventListener(Event.COMPLETE, onCommandComplete);
			command.execute();
		}
		
		protected function removeEvents():void{
			var command:Command;
			
			for each(command in _items){
				if(command.hasEventListener(Event.COMPLETE)){
					try{
						command.removeEventListener(Event.COMPLETE, onCommandComplete);
					}
					catch(e:Error){}
				}
			}
		}
		
		protected function onCommandComplete(event:Event):void{
			Command(event.target).removeEventListener(Event.COMPLETE, onCommandComplete);
			_index++;
			
			if(_index == _items.length) complete();
			else if(isSequential) executeItem(_index);
		}
	}
}